﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;

namespace FoundationLib.Web.Converters
{
	/// <summary>
	/// A converter that encodes text as HTML.
	/// </summary>
	public class HtmlEncodeConverter : IConverter
	{
		/// <summary>
		/// The converter options.
		/// </summary>
		private HtmlEncodeConverterOptions options;


		/// <summary>
		/// Creates a new <see cref="HtmlEncodeConverter"/>.
		/// </summary>
		public HtmlEncodeConverter()
		{
			this.options = HtmlEncodeConverterOptions.EncodeHtml;
		}

		/// <see cref="IConverter.SupportsOptions"/>
		public bool SupportsOptions
		{
			get
			{
				return true;
			}
		}

		/// <see cref="IConverter.Convert(object, ConversionDirection)"/>
		public object Convert(object input, ConversionDirection direction)
		{
			if (!(input is string))
				throw new ArgumentException("The input must be a string.", "input");

			string inputString = input as string;
			string outputString = null;

			if (direction == ConversionDirection.In)
			{
				if ((this.options & HtmlEncodeConverterOptions.EncodeHtml) == HtmlEncodeConverterOptions.EncodeHtml)
					outputString = HttpUtility.HtmlDecode(inputString);
				if ((this.options & HtmlEncodeConverterOptions.EncodeLineBreaks) == HtmlEncodeConverterOptions.EncodeLineBreaks)
				{
					outputString = outputString.Replace("<br/>", Environment.NewLine)
						.Replace("<br>", Environment.NewLine).Replace("<br />", Environment.NewLine);
				}
			}
			else
			{
				if ((this.options & HtmlEncodeConverterOptions.EncodeHtml) == HtmlEncodeConverterOptions.EncodeHtml)
					outputString = HttpUtility.HtmlEncode(inputString);
				if ((this.options & HtmlEncodeConverterOptions.EncodeLineBreaks) == HtmlEncodeConverterOptions.EncodeLineBreaks)
					outputString = outputString.Replace("\r", "").Replace("\n", "<br/>");
			}

			return outputString;
		}

		/// <see cref="IConverter.Convert(object, ConversionDirection, object)"/>
		public bool TryConvert(object input, ConversionDirection direction, out object output)
		{
			try
			{
				output = this.Convert(input, direction);
				return true;
			}
			catch (Exception)
			{
				output = null;
				return false;
			}
		}

		/// <see cref="IConverter.Options"/>
		public object Options
		{
			get
			{
				return this.options;
			}
			set
			{
				this.options = (HtmlEncodeConverterOptions)value;
			}
		}
	}
}
